#ifndef __LUA_PARSER__
#define __LUA_PARSER__
#include <QString>
#include <QHash>
#include <globalsink.h>
#include "../luac_parser/luablock.h"

//using namespace std;
struct LexState;
class TokenParser;


const int REFERENCE_NOT_FOUND = -1;

class LuaParser
{    
protected:
    TokenParser * m_tokenParser;
    QHash<QString, int> m_globalsCache;
    QHash<QString, int> m_globalFunctionsCache;
    QHash<QString, int> m_localFunctionsCache;
    QHash<QString, QString> m_globalsToFunctionsMap;
    LuaBlock * m_root;
    LuaBlock * m_currentBlock;
    const char * m_data;
    int m_dataLength;
public:
	LuaParser();
    ~LuaParser();
    void parseData(QString aData);
    /*void processLongComments();
    void processShortComments();
    void processShortStrings();
    void processLongStrings();    */
	void clearNodes();
    TokenParser * getTokenParser();
    void collectGlobalFunctions(LuaBlock *aRoot);
    void cacheGlobalFunction(QString aName, int aOffset);
    QString readFunctionName(LuaBlock *aFunction, int &aOffset, bool aIncludeParams, QString &aNameWithoutParameters);
    void resetBlocks();
    void startBlock(LuaBlockTypeEnum aType, LexState * aState);
    void endBlock(LexState *aState);
    void setCurrentBlockType(LuaBlockTypeEnum aType);
    void collectLocalFunctions(LuaBlock *aRoot);
    LuaBlock * getEnclosingBlock(int aOffset);
    //returns offset of local variable declaration named aWord
    int getLocalReference(QString aWord, int aOffset);
    int getLocalReferenceFromBlock(LuaBlock * aBlock, QString aWord, LuaBlock * aStopAtBlock);
    int findMatchingLocalFunctionDeclaration(LuaBlock *aBlock, QString aMatch);
    int findMatchingLocalVariableDeclaration(LuaBlock *aBlock, QString aMatch);
    void collectGlobalReferences();
    void cacheGlobal(QString aName, int aOffset);
    int getGlobalReference(QString aWord);
    void getLocalCompletions(QString aPrefix, int aOffset, QStringList &aSink);
    void getLocalCompletionsFromBlock(LuaBlock *aBlock, QString aWord, LuaBlock *aStopAtBlock, QStringList &aSink);
    void collectAllMatchingLocalVariableDeclarations(LuaBlock *aBlock, QString aPrefix, QStringList &aSink);
    QString readMatchingLocalFunctionDeclaration(LuaBlock *aBlock);
    void getGlobalCompletions(QString aPrefix, QStringList &aSink);
    void getAllGlobalReferences(QString aPrefix, QStringList &aTextSink, QStringList &aLinkSink, QString aFile);
};
#endif
